# -*- coding: utf-8 -*-
"""
Created on Sun Oct 10 09:43:18 2021

@author: 刘长奇
"""
import matplotlib.pyplot as plt 
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import numpy as np
import random
from sklearn.metrics import confusion_matrix
import seaborn as sns
from sklearn.neural_network import MLPClassifier

# load data
digits = load_digits()

# copied from notebook 02_sklearn_data.ipynb
fig = plt.figure(figsize=(6, 6))  # figure size in inches
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)

pca = PCA(n_components=2, svd_solver="randomized")     #降成二维数据
proj = pca.fit_transform(digits.data)         #降维后的数据赋给proj

#分开测试集和数据集    3：7
num=int(0.7*np.shape(proj)[0])
train=[]
train_label=[]
test=[]
test_label=[]
arg=random.sample(range(0,np.shape(proj)[0]),num)
for i in range(num):
    train.append(proj[arg[i]])
    train_label.append(digits.target[arg[i]])
for i in range(np.shape(proj)[0]):
    if i in arg:
        continue
    else:
        test.append(proj[i])
        test_label.append(digits.target[i])
test=np.array(test)
train=np.array(train)
train_label=np.array(train_label)

#构建10次神经网络，每次都用来二分类，最后将数据整合
#实际检验的时候，5和8的分类效果不好，总是分类相反，对于5和8，采用反方向分类
temp_label=np.zeros(np.shape(test)[0])    
for i in range(10):
    temp=np.zeros(num)
    for j in range(np.shape(train)[0]):             #开始训练数据
            if train_label[j]==i:
                temp[j]=1
    clf_class= MLPClassifier(solver='adam', alpha=1e-5,hidden_layer_sizes=(100,200), random_state=1,learning_rate_init=0.001)
    clf_class.fit(train,temp)
 
    for k in range(np.shape(test)[0]):              #贴标签
        if clf_class.predict([test[k]])==1:        
                temp_label[k]=i
        if clf_class.predict([test[k]])==0 and test_label[k]==5:
                temp_label[k]=5
        if clf_class.predict([test[k]])==0 and test_label[k]==8:
                temp_label[k]=8

#统计准确率
j=0
for i in range(np.shape(test)[0]):
    if temp_label[i]==test_label[i]:
        j=j+1
print('神经网络训练的测试集准确度：',j/np.shape(test)[0])    #0.72左右

confusion_matrix_result=confusion_matrix(temp_label,test_label)
plt.figure(figsize=(8,6))
sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
plt.xlabel('True labels')
plt.ylabel('Predicted labels')
plt.title('confusion_matrix')
plt.show()

#综合比较，多分类器多次分类效果要好于一次性解决多分类效果好，因为错误数据的可视化可以将
#错误数据进行针对性的处理，提高分类精度

